using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Net.Mail;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.Agreements;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.Policy;
using PHSRAG.Utility;
using Helper = PHSRAG.WebControls.Helper;

namespace PHSRAG.Insight21.Admin
{
    /// <summary>
    /// This page, Sponsor Addition allows users to add new sponors to (in this order) Rex, InfoEd, Insight.
    /// </summary>
    public partial class SponsorAddition : BasePage
    {
        # region Constants

        private const string CurrentPageIndexKey = "currentPageIndexKey_27447545-6976-4179-A0A7-B3AFED489466";
        private const string SelectMergeCommand = "SelectMergeCommand";
        private const string SelectSponsorCommand = "SelectSponsorCommand";

        #endregion

        #region Private Types

        /// <summary>Enumeration for the columns contained in the datagrid </summary>
        private enum ColumnIndex
        {
            Id,
            Name,
            ShortName,
            SponsorType
        }

        #endregion

        #region Instance Variables (Private)

        private ICachePolicy objectCachePolicy;
        private ICachePolicy pageCachePolicy;
        private ICachePolicy viewStateCachePolicy;

        #endregion

        #region event handlers

        /// <summary>
        /// Resets the subnavigation selected link(s) before the 
        /// header performs a redirect, and purges the Buisness Objects 
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnHeaderNavigate(object sender, CommandEventArgs e)
        {
            PurgeCache();
            adminSubNavigation.Reset();
        }

        /// <summary>
        /// Purges the Buisness Objects before doing a redirect  
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnSubNavigate(object sender, CommandEventArgs e)
        {
            PurgeCache();
        }

        /// <summary>
        ///Adds the breadcrumb and initializes the dropdown of types
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Page_Load(object sender, EventArgs e)
        {
            try
            {
                breadCrumb.Add("Sponsor Addition", "SponsorAddition.aspx", Settings.GetKeyValue("BreadCrumb.SummaryPageLevel", 2));

                if (IsPostBack)
                {
                    mergePanel.Visible = string.Empty != mergeId.Text;
                }
                else
                {
                    dataGrid.PageSize = Settings.GetKeyValue("DataGrid.ItemsPerPage", 10);
                    InitializeDropDownList(sponsorType, Sponsors.GetSponsorTypes(DataAccess.GetConnectionString()), "Name", "Id");
                    InitializeDropDownList(country, GetInfoEdCountries(), "CountryName", "CountryCode");
                    ManagePagination();
                }

                object id = viewStateCachePolicy.GetCachedObject(Keys.SponsorIdKey);

                if (id == null)
                {
                    // Ensure the page expires in the event the backbutton
                    // is used and no Sponsor Id has been selected.
                    // This will avoid the user from entering a duplicate
                    // sponsor.
                    Response.Buffer = true;
                    Response.ExpiresAbsolute = DateTime.Now - (new TimeSpan(0, 1, 0, 0, 0));
                    Response.Expires = 0;
                    Response.CacheControl = "no-cache";
                }

                annunciator.Message = string.Empty;
            }
            catch (Exception ex)
            {
                annunciator.Message = ex.Message;
            }
        }

        /// <summary>
        /// If the page has all required fields, instigates the following: Insert into Rex, InfoEd, Insight
        /// Send email to the helpdesk if the user is not a system admin, CC the logged in user who submitted this sponsor
        /// After submitting, reset the controls
        /// </summary>
        protected void OnSubmitSponsor(object sender, ImageClickEventArgs e)
        {
            try
            {
                if (Page.IsValid)
                {
                    UserContext userContext = (UserContext) objectCachePolicy.GetCachedObject(UserContext.CacheKey);
                    Sponsor sponsor = new Sponsor(objectCachePolicy);

                    object id = viewStateCachePolicy.GetCachedObject(Keys.SponsorIdKey);

                    if (id != null)
                    {
                        sponsor.Load(DataAccess.GetConnectionString(), (int) id);
                    }

                    sponsor.SponsorTypeId = sponsorType.SelectedItem.Value;
                    sponsor.SponsorTypeName = sponsorType.SelectedItem.Text;
                    DataTable sponsorTypeTable = Sponsors.GetSponsorTypes(DataAccess.GetConnectionString());
                    DataRow[] sponsorTypes = sponsorTypeTable.Select(string.Format("Id = '{0}'", sponsor.SponsorTypeId));

                    if (sponsorTypes.Length > 0)
                    {
                        sponsor.InfoEdSponsorType = sponsorTypes[0]["PSCode"].ToString();
                    }

                    sponsor.Name = name.Text.Trim();
                    sponsor.ShortName = shortName.Text.Trim();
                    sponsor.Description = comments.Text.Trim();
                    sponsor.PSCustCode = PSAcct.Text.Trim();
                    sponsor.Street = street.Text.Trim();
                    sponsor.City = city.Text.Trim();
                    sponsor.State = state.Text.Trim();
                    sponsor.ZipCode = zipCode.Text.Trim();

                    if (country.SelectedIndex != 0)
                    {
                        sponsor.Country = GetInfoEdCountries().Rows[country.SelectedIndex - 1][0].ToString();
                    }
                    sponsor.EmailAddress = email.Text.Trim();
                    sponsor.Street2 = street2.Text.Trim();
                    sponsor.ICRate = icRate.Text == "" ? 0 : Convert.ToDecimal(icRate.Text);

                    sponsor.Save(DataAccess.GetConnectionString());

                    if (string.Empty != mergeId.Text)
                    {
                        sponsor.Merge(Convert.ToInt32(mergeId.Text));
                    }

                    if (!userContext.IsUserSysAdmin &&
                        Settings.GetKeyValue("SponsorAdditionPageEmailOn", false))
                    {
                        StringBuilder mailBody = new StringBuilder();
                        MailMessage sponsorMailMessage = new MailMessage("helpdesk@partners.org", "helpdesk@partners.org");
                        sponsorMailMessage.CC.Add(userContext.EmailAddress);
                        sponsorMailMessage.CC.Add("mmullahy@partners.org");
                        sponsorMailMessage.Subject = "A New Sponsor Has Been Added/Updated";
                        mailBody.AppendFormat("The following sponsor has been added/updated: Name: {0}   Short Name: {1}   Sponsor Type: {2}  PS Account #: {3}  Street: {4}  City: {5}  State: {6}  Zip Code: {7}   Sponsor Email: {8}  Indirect cost rate/base: {9}  Comments/Description: {10}", name.Text, shortName.Text, sponsorType.SelectedValue, PSAcct.Text, street.Text, city.Text, state.Text, zipCode.Text, email.Text, icRate.Text, comments.Text);
                        sponsorMailMessage.Body = mailBody.ToString();
                        SmtpClient client = new SmtpClient("SMTP.Partners.org");
                        client.Send(sponsorMailMessage);
                    }

                    LoadDataGrid();
                    ManagePagination();

                    mergePanel.Visible = false;
                    mergeText.Text = string.Empty;
                    mergeId.Text = string.Empty;

                    viewStateCachePolicy.Cache(Keys.SponsorIdKey, sponsor.Id);
                }
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred:";
                annunciator.Message = null == ex.InnerException ? ex.Message : string.Format("{0} ({1})", ex.Message, ex.InnerException.Message);
            }
        }

        /// <summary>
        /// Validates that the sponsor dropdown has a valid selection 
        /// </summary>
        protected void OnSponsorTypeValidate(object source, ServerValidateEventArgs args)
        {
            args.IsValid = !(sponsorType.SelectedValue == Helper.SelectPrompt);
        }

        /// <summary>
        /// Sets the page index to the last page, loads the grid and adjusts
        /// the pager controls navigation links.
        /// </summary>
        protected void OnLastPage(object sender, CommandEventArgs e)
        {
            try
            {
                CurrentPageIndex = pagerAboveDatagrid.PageCount - 1;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred navigating to last page:";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }

        /// <summary>
        /// When a sponsor name is clicked on, load that sponsor's information into each of the textboxes and dropdowns 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        protected void OnItemCommand(object source, DataGridCommandEventArgs e)
        {
            try
            {
                if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
                {
                    if (e.CommandName == SelectSponsorCommand)
                    {
                        Sponsor sponsor = new Sponsor(objectCachePolicy);
                        sponsor.Load(DataAccess.GetConnectionString(), Convert.ToInt32(e.Item.Cells[(int) ColumnIndex.Id].Text));
                        name.Text = sponsor.Name;
                        shortName.Text = sponsor.ShortName;
                        comments.Text = sponsor.Description;
                        sponsorType.SelectedValue = sponsor.SponsorTypeId;
                        PSAcct.Text = sponsor.PSCustCode;
                        street.Text = sponsor.Street;
                        street2.Text = sponsor.Street2;
                        city.Text = sponsor.City;
                        state.Text = sponsor.State;
                        zipCode.Text = sponsor.ZipCode;
                        email.Text = sponsor.EmailAddress;
                        icRate.Text = sponsor.ICRate.ToString();
                        rexId.Text = Convert.ToString(sponsor.RexSponsorId);
                        infoEdSponCode.Text = sponsor.InfoEdSponCode;

                        DataTable infoedcountries = GetInfoEdCountries();
                        bool countrySet = false;

                        if (null != sponsor.Country)
                        {
                            for (int i = 0; i < infoedcountries.Rows.Count; i++)
                            {
                                if (infoedcountries.Rows[i][0].ToString() == sponsor.Country)
                                {
                                    country.SelectedIndex = i + 1;
                                    countrySet = true;
                                    break;
                                }
                            }
                        }

                        if (!countrySet)
                        {
                            country.SelectedIndex = -1;
                        }

                        viewStateCachePolicy.Cache(Keys.SponsorIdKey, sponsor.Id);
                        UserContext userContext = (UserContext) objectCachePolicy.GetCachedObject(UserContext.CacheKey);

                        if (!userContext.IsUserSysAdmin)
                        {
                            name.Enabled = false;
                        }
                    }
                    else if (e.CommandName == SelectMergeCommand)
                    {
                        Sponsor sponsor = new Sponsor(objectCachePolicy);
                        sponsor.Load(DataAccess.GetConnectionString(), Convert.ToInt32(e.Item.Cells[(int) ColumnIndex.Id].Text));

                        mergeText.Text =
                            string.Format("{0}: InfoEd Spon Code ({1}): ReX Id ({2})",
                                sponsor.Name, sponsor.InfoEdSponCode, Convert.ToString(sponsor.RexSponsorId));
                        mergeId.Text = Convert.ToString(sponsor.Id);
                        mergePanel.Visible = true;
                    }
                }
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred:";
                annunciator.Message = null == ex.InnerException ? ex.Message : string.Format("{0} ({1})", ex.Message, ex.InnerException.Message);
            }
        }

        /// <summary>
        /// If not on the last page, increments the page index, loads the grid and adjusts
        /// the pager controls navigation links.
        /// </summary>
        protected void OnNextPage(object sender, CommandEventArgs e)
        {
            try
            {
                ++CurrentPageIndex;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred navigating to next page:";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }

        /// <summary>
        /// If the current page is greater than 0, decrements the current page index,
        /// loads the data grid and adjusts the pager controls navigation links.
        /// </summary>
        protected void OnPreviousPage(object sender, CommandEventArgs e)
        {
            try
            {
                --CurrentPageIndex;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred navigating to previous page:";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }

        /// <summary>
        /// Sets the page index to zero, loads the grid 
        /// </summary>
        protected void OnFirstPage(object sender, CommandEventArgs e)
        {
            try
            {
                CurrentPageIndex = 0;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred navigating to previous page:";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }

        /// <summary>
        /// Sets the page index to zero, loads the grid with the criteria from the search
        /// </summary>
        protected void OnSearchSponsors(object sender, ImageClickEventArgs e)
        {
            try
            {
                ResultsCache.PurgeObject(objectCachePolicy);
                CurrentPageIndex = 0;
                LoadDataGrid();
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred navigating to previous page:";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }

        /// <summary>
        /// Resets all of the controls to empty and clears the datagrid, and purge anything cached since we are clearing  
        /// </summary>
        protected void OnClearSponsors(object sender, ImageClickEventArgs e)
        {
            nameSearch.Text = string.Empty;
            shortNameSearch.Text = string.Empty;

            ResetInputControls();

            dataGrid.DataSource = null;
            dataGrid.DataBind();
            ManagePagination();

            PurgeCache();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Loads the sponsors based on the criteria in the textboxes
        /// </summary>
        private Sponsors Sponsors
        {
            get
            {
                Sponsors sponsors =
                    ResultsCache.GetObject(objectCachePolicy, Sponsors.CacheKey) as Sponsors;

                if (null == sponsors)
                {
                    sponsors = new Sponsors(objectCachePolicy);
                    sponsors.Load(DataAccess.GetConnectionString(), nameSearch.Text.Trim(), shortNameSearch.Text.Trim());
                    ResultsCache.SetObject(objectCachePolicy, Sponsors.CacheKey, sponsors);
                }

                return sponsors;
            }
        }

        /// <summary>
        /// Gets/Sets the current page index  
        /// </summary>
        private int CurrentPageIndex
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.SponsorAdditionPageKey) as Hashtable;
                return (h == null || h[CurrentPageIndexKey] == null) ? 0 : (int) h[CurrentPageIndexKey];
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(Keys.SponsorAdditionPageKey) as Hashtable ?? new Hashtable();
                h[CurrentPageIndexKey] = value;
                dataGrid.CurrentPageIndex = value;
                pageCachePolicy.Cache(Keys.SponsorAdditionPageKey, h);
            }
        }

        private DataTable GetInfoEdCountries()
        {
            SqlConnection infoEdConnection = new SqlConnection(DataAccess.GetConnectionString("InfoEdStaging"));
            infoEdConnection.Open();
            SqlTransaction infoEdTransaction = infoEdConnection.BeginTransaction();
            string infoEdCountryCodeString = "Select * from CountryCodes";
            SqlCommand infoEdCountryCodes = new SqlCommand(infoEdCountryCodeString);
            infoEdCountryCodes.Transaction = infoEdTransaction;
            infoEdCountryCodes.Connection = infoEdConnection;
            SqlDataAdapter adapter = new SqlDataAdapter(infoEdCountryCodeString, infoEdConnection);
            adapter.SelectCommand = infoEdCountryCodes;
            DataTable infoEdCountriesDT = new DataTable("infoEdCountriesDT");
            adapter.Fill(infoEdCountriesDT);
            infoEdConnection.Close();
            return infoEdCountriesDT;
        }

        /// <summary>
        /// Loads the data and makes sure that the page count is appropriate
        /// Also determines if the datagrid should be visible or not 
        /// </summary>
        private void LoadDataGrid()
        {
            try
            {
                Sponsors sponsors = Sponsors;

                dataGrid.VirtualItemCount = pagerBelowDatagrid.RecordCount = pagerAboveDatagrid.RecordCount = sponsors.SponsorList.Count;

                int currentPageIndex = CurrentPageIndex;
                int pageCount = (pagerAboveDatagrid.RecordCount/dataGrid.PageSize) +
                    (((pagerAboveDatagrid.RecordCount%dataGrid.PageSize) == 0) ? 0 : 1);
                pagerBelowDatagrid.PageCount = pagerAboveDatagrid.PageCount = pageCount;
                pagerBelowDatagrid.CurrentPage = pagerAboveDatagrid.CurrentPage = currentPageIndex + 1;

                dataGrid.DataSource = sponsors.GetSponsorsArrayList(currentPageIndex*dataGrid.PageSize, dataGrid.PageSize, objectCachePolicy);
                dataGrid.DataBind();
                ManagePagination();

                if (dataGrid.Items.Count <= 0)
                {
                    dataGrid.Visible = false;
                    annunciator.Message = "No sponsors found matching the search criteria.";
                }
                else
                {
                    dataGrid.Visible = true;
                }
            }
            catch
            {
                dataGrid.Visible = pagerAboveDatagrid.Visible = pagerBelowDatagrid.Visible = false;
                throw;
            }
        }

        /// <summary>
        /// Manage the pages of the datagrid 
        /// </summary>
        private void ManagePagination()
        {
            if (pagerBelowDatagrid.Visible = pagerAboveDatagrid.Visible = (dataGrid.Items.Count > 0))
            {
                int currentPageIndex = CurrentPageIndex;
                dataGrid.CurrentPageIndex = currentPageIndex;

                int startIndex = currentPageIndex*dataGrid.PageSize;

                pagerBelowDatagrid.FirstRecord = pagerAboveDatagrid.FirstRecord = startIndex + 1;
                pagerBelowDatagrid.LastRecord = pagerAboveDatagrid.LastRecord =
                    Math.Min(startIndex + dataGrid.PageSize, dataGrid.VirtualItemCount);

                pagerBelowDatagrid.EnableFirstPage = pagerAboveDatagrid.EnableFirstPage =
                    pagerBelowDatagrid.EnablePreviousPage = pagerAboveDatagrid.EnablePreviousPage =
                        (CurrentPageIndex != 0);

                pagerBelowDatagrid.EnableLastPage = pagerAboveDatagrid.EnableLastPage =
                    pagerBelowDatagrid.EnableNextPage = pagerAboveDatagrid.EnableNextPage =
                        (CurrentPageIndex != (pagerAboveDatagrid.PageCount - 1));
            }
        }

        /// <summary>
        /// Purge any cached business objects before leaving the page 
        /// </summary>		
        private void PurgeCache()
        {
            ResultsCache.PurgeObject(objectCachePolicy);
        }

        /// <summary>
        /// Resets all of the controls on the page to empty 
        /// </summary>
        private void ResetInputControls()
        {
            name.Text = string.Empty;
            shortName.Text = string.Empty;
            comments.Text = string.Empty;
            sponsorType.ClearSelection();
            PSAcct.Text = string.Empty;
            street.Text = string.Empty;
            street2.Text = string.Empty;
            city.Text = string.Empty;
            state.Text = string.Empty;
            zipCode.Text = string.Empty;
            icRate.Text = string.Empty;
            email.Text = string.Empty;
            rexId.Text = string.Empty;
            infoEdSponCode.Text = string.Empty;
            country.ClearSelection();
            name.Enabled = true;

            mergePanel.Visible = false;
            mergeText.Text = string.Empty;
            mergeId.Text = string.Empty;

            viewStateCachePolicy.Cache(Keys.SponsorIdKey, null);
        }

        /// <summary>
        /// Initialize the specified drop-down-list with data and add the "-- Select --" item as the first item.
        /// </summary>
        /// <param name="ddl">Drop-down-list to initialize</param>
        /// <param name="dataSource">Datasource for the drop-down-list</param>
        /// <param name="dataTextField">Name of the entity within the datasource which contains data for binding</param>
        private void InitializeDropDownList(DropDownList ddl, DataTable dataSource, string dataTextField, string dataValueField)
        {
            string selection = (ddl.SelectedIndex < 0) ? string.Empty : ddl.SelectedItem.Text;
            ddl.DataSource = dataSource;
            ddl.DataTextField = dataTextField;
            ddl.DataValueField = dataValueField;
            ddl.DataBind();

            if (ddl.Enabled = (ddl.Items.Count > 0))
            {
                ddl.Items.Insert(0, Helper.SelectPrompt);
                if (selection != string.Empty)
                {
                    ListItem item = ddl.Items.FindByText(selection);
                    if (item != null)
                    {
                        item.Selected = true;
                    }
                }
            }
        }

        #endregion

        #region Web Form Designer generated code

        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //

            InitializeComponent();
            base.OnInit(e);

            objectCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
            viewStateCachePolicy = new Policy.ViewStateCachePolicy(ViewState);
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
        }

        #endregion
    }
}